<template>
  <div>
    <a-card>
      <a-space>
        <a-input
          v-model:value="listQuery.userId"
          placeholder="输入工号搜索"
          allow-clear
          @keyup.enter="handleFilter"
        />
        <a-select
          v-model:value="listQuery.status"
          allow-clear
          :options="[
            { label: '正常', value: 'NORMAL' },
            { label: '冻结', value: 'FREEZE' },
            { label: '离职', value: 'LEAVE' },
          ]"
          placeholder="状态"
          style="width: 100px"
          @change="handleFilter"
        />
        <a-button type="primary" :icon="h(SearchOutlined)" @click="handleFilter">搜索</a-button>
      </a-space>
    </a-card>
    <a-card class="mt-2">
      <a-space class="mb-4">
        <a-button
          :icon="h(PlusOutlined)"
          v-if="hasPermission(['user:add'])"
          type="primary"
          @click="handleAdd"
        >
          添加用户
        </a-button>
        <a-button :icon="h(DownloadOutlined)" @click="handleExport">导出数据</a-button>
        <a-button
          v-if="checkedRowKeysRef.length && hasPermission(['user:delete'])"
          type="primary"
          danger
          :icon="h(DeleteOutlined)"
          @click="handleBatchDelete"
        >
          批量删除
        </a-button>
      </a-space>
      <div class="tree-table-wrapper">
        <div class="tree-wrapper">
          <a-tree
            v-if="showTree"
            default-expand-all
            block-node
            :tree-data="treeData"
            :field-names="{
              children: 'children',
              title: 'deptName',
              key: 'deptId',
            }"
            @select="handleTreeSelect"
          />
        </div>
        <div class="flex-1">
          <a-table
            ref="table"
            bordered
            :columns="columns"
            :data-source="data"
            :pagination="pagination"
            :loading="tableLoading"
            :row-key="(row) => row.userId + ''"
            :row-selection="
              hasPermission(['user:delete'])
                ? {
                    fixed: true,
                    preserveSelectedRowKeys: true,
                    selectedRowKeys: checkedRowKeysRef,
                    onChange: handleCheck,
                  }
                : null
            "
          >
            <template #bodyCell="{ column, record }">
              <template v-if="column.dataIndex === 'status'">
                <a-tag v-if="record.status === 'NORMAL'" color="success">
                  <template #icon>
                    <check-circle-outlined />
                  </template>
                  正常
                </a-tag>
                <a-tag v-else-if="record.status === 'FREEZE'" color="processing">
                  <template #icon>
                    <clock-circle-outlined />
                  </template>
                  冻结
                </a-tag>
                <a-tag v-else>
                  <template #icon>
                    <minus-circle-outlined />
                  </template>
                  离职
                </a-tag>
              </template>
              <template v-else-if="column.dataIndex === 'actions'">
                <a-button
                  v-if="hasPermission(['user:edit'])"
                  size="small"
                  type="link"
                  @click="handleEdit(record)"
                >
                  <a-tooltip>
                    <template #title>编辑</template>
                    <EditOutlined />
                  </a-tooltip>
                </a-button>
                <a-button
                  v-if="hasPermission(['user:delete'])"
                  size="small"
                  type="link"
                  danger
                  @click="handleDelete(record)"
                >
                  <a-tooltip>
                    <template #title>删除</template>
                    <DeleteOutlined />
                  </a-tooltip>
                </a-button>
                <a-button
                  v-if="hasPermission(['user:reset'])"
                  size="small"
                  type="link"
                  @click="handleResetPwd(record)"
                >
                  <a-tooltip>
                    <template #title>重置密码</template>
                    <UndoOutlined />
                  </a-tooltip>
                </a-button>
              </template>
            </template>
          </a-table>
        </div>
      </div>
    </a-card>
    <a-modal
      v-model:open="showModal"
      :mask-closable="false"
      :keyboard="false"
      :title="title"
      :confirm-loading="formBtnLoading"
      width="740px"
      @ok="handleConfirm"
    >
      <a-form ref="formRef" :model="form" :rules="rules" :label-col="{ span: 4 }" class="pt-1">
        <div class="grid grid-cols-2 cg-4">
          <a-form-item label="工号" name="userId">
            <a-input v-model:value="form.userId" disabled />
          </a-form-item>
          <a-form-item label="姓名" name="nickname">
            <a-input
              v-model:value="form.nickname"
              placeholder="请输入姓名"
              show-count
              allow-clear
              :maxlength="12"
            />
          </a-form-item>
          <a-form-item label="手机" name="phone">
            <a-input
              v-model:value="form.phone"
              placeholder="请输入手机"
              show-count
              allow-clear
              :maxlength="11"
            />
          </a-form-item>
          <a-form-item label="邮箱" name="email">
            <a-input
              v-model:value="form.email"
              placeholder="请输入邮箱"
              allow-clear
              show-count
              :maxlength="99"
            />
          </a-form-item>
          <a-form-item label="角色" name="roleIds">
            <a-select
              v-model:value="form.roleIds"
              mode="multiple"
              :options="roleList"
              option-filter-prop="roleName"
              :max-tag-count="2"
              :max-tag-text-length="4"
              :field-names="{
                label: 'roleName',
                value: 'roleId',
              }"
            />
          </a-form-item>
          <a-form-item label="部门" name="deptId">
            <a-tree-select
              v-model:value="form.deptId"
              show-search
              style="width: 100%"
              placeholder="请选择"
              allow-clear
              tree-default-expand-all
              :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
              :tree-data="treeData"
              :field-names="{
                children: 'children',
                label: 'deptName',
                value: 'deptId',
              }"
              tree-node-filter-prop="deptName"
            />
          </a-form-item>
          <a-form-item label="上级" name="leaderId">
            <a-select
              v-model:value="form.leaderId"
              show-search
              placeholder="输入工号/姓名搜索"
              :default-active-first-option="false"
              :show-arrow="false"
              :filter-option="false"
              :not-found-content="null"
              :options="leaderOpts"
              @search="getLeaderOpts"
            />
          </a-form-item>
          <a-form-item label="岗位" name="postId">
            <a-select
              v-model:value="form.postId"
              show-search
              placeholder="输入岗位名称搜索"
              :default-active-first-option="false"
              :show-arrow="false"
              :filter-option="false"
              :not-found-content="null"
              :options="postOpts"
              @search="getPostOpts"
            />
          </a-form-item>
          <a-form-item label="状态" name="status">
            <a-select
              v-model:value="form.status"
              :options="[
                { label: '正常', value: 'NORMAL' },
                { label: '冻结', value: 'FREEZE' },
                { label: '离职', value: 'LEAVE' },
              ]"
              placeholder="状态"
            />
          </a-form-item>
        </div>
      </a-form>
    </a-modal>
  </div>
</template>

<script setup lang="ts">
  import { h, onMounted, reactive, ref, watch } from 'vue';
  import UserApi from '@/api/UserApi';
  import {
    DeleteOutlined,
    DownloadOutlined,
    EditOutlined,
    PlusOutlined,
    SearchOutlined,
    UndoOutlined,
    CheckCircleOutlined,
    ClockCircleOutlined,
    MinusCircleOutlined,
  } from '@ant-design/icons-vue';
  import RoleApi from '@/api/RoleApi';
  import { usePermission } from '@/hooks/usePermission';
  import { download, resetReactive } from '@/utils';
  import { message, Modal } from 'ant-design-vue';
  import { Rule } from 'ant-design-vue/es/form';
  import DeptApi from '@/api/DeptApi';
  import PostApi from '@/api/PostApi';

  const { hasPermission } = usePermission();

  const columns = [
    { title: '工号', dataIndex: 'userId' },
    { title: '姓名', dataIndex: 'nickname' },
    {
      title: '部门',
      dataIndex: 'dept',
      ellipsis: true,
    },
    {
      title: '岗位',
      dataIndex: 'post',
      ellipsis: true,
    },
    {
      title: '直属上级',
      dataIndex: 'leader',
      ellipsis: true,
    },
    {
      title: '状态',
      dataIndex: 'status',
      align: 'center',
      width: 100,
    },
  ];
  const actionColum = {
    title: '操作',
    dataIndex: 'actions',
    align: 'center',
    fixed: 'right',
    width: 130,
  };

  if (hasPermission(['user:edit', 'user:delete', 'user:reset'])) {
    columns.push(actionColum);
  }

  let data = ref([]);
  const pagination = reactive({
    current: 1,
    pageSize: 10,
    total: 0,
    onChange: (current: number) => {
      pagination.current = current;
      getList();
    },
  });
  onMounted(() => {
    getRoleList();
    getDeptList();
    getPostOpts();
    getList();
  });

  const listQuery = reactive<any>({});

  const tableLoading = ref(false);

  function getList() {
    tableLoading.value = true;
    UserApi.page({ index: pagination.current, size: pagination.pageSize, ...listQuery })
      .then((res) => {
        data.value = res.data;
        pagination.total = res.total;
        leaderOpts.value = res.data.map((i) => {
          return { label: `${i.userId} - ${i.nickname}`, value: i.userId };
        });
      })
      .finally(() => (tableLoading.value = false));
  }

  const showTree = ref(false);

  let treeData = ref([]);

  function getDeptList() {
    DeptApi.tree()
      .then((res) => {
        treeData.value = res.data;
      })
      .finally(() => {
        showTree.value = true;
      });
  }

  let postOpts = ref([]);

  function getPostOpts(postName) {
    PostApi.page({ postName, index: 1, size: 20 }).then((res) => {
      postOpts.value = res.data.map((i) => {
        return { label: i.postName, value: i.postId };
      });
    });
  }

  let leaderOpts = ref([]);

  function getLeaderOpts(keyword) {
    UserApi.userOpts(keyword).then((res) => {
      leaderOpts.value = res.data.map((i) => {
        return { label: `${i.userId} - ${i.nickname}`, value: i.userId };
      });
    });
  }

  function handleTreeSelect(selectedKeys) {
    if (selectedKeys.length) {
      listQuery.deptId = selectedKeys[0];
    } else {
      delete listQuery.deptId;
    }
    handleFilter();
  }

  const roleList = ref<Role[]>([]);

  function getRoleList() {
    RoleApi.list({}).then((res) => {
      roleList.value = res.data;
    });
  }

  function getCheckedRoles() {
    UserApi.getRoles(form.userId).then((res) => {
      form.roleIds = res.data;
    });
  }

  function handleFilter() {
    pagination.current = 1;
    getList();
  }

  const showModal = ref(false);
  const title = ref('');
  const formRef = ref();
  const form = reactive<User>({});
  const rules: Record<string, Rule[]> = {
    nickname: [{ required: true, trigger: 'blur', message: '请输入姓名' }],
    deptId: [{ required: true, trigger: 'change', message: '请选择部门' }],
    postId: [{ required: true, trigger: 'change', message: '请选择岗位' }],
    leaderId: [{ required: true, trigger: 'change', message: '请选择直属上级' }],
    roleIds: [{ required: true, trigger: ['blur', 'change'], message: '请选择角色' }],
  };

  watch(
    () => form.phone,
    (val, preVal) => {
      const reg = /^\d*$/;
      if (reg.test(val) || !val) {
        form.phone = val;
      } else {
        form.phone = preVal ? preVal : '';
      }
    }
  );

  function handleEdit(row) {
    showModal.value = true;
    title.value = '编辑';
    Object.assign(form, row);
    formRef.value?.clearValidate();
    getCheckedRoles();
  }

  function handleAdd() {
    showModal.value = true;
    title.value = '添加';
    resetReactive(form);
    formRef.value?.clearValidate();
  }

  const formBtnLoading = ref(false);

  function handleConfirm() {
    formRef.value
      .validate()
      .then(() => {
        formBtnLoading.value = true;
        (form.userId ? UserApi.update(form) : UserApi.save(form))
          .then(() => {
            message.success('提交成功');
            showModal.value = false;
            getList();
          })
          .finally(() => {
            formBtnLoading.value = false;
          });
      })
      .catch(() => {});
  }

  function handleDelete(row) {
    Modal.confirm({
      title: '提示',
      content: '确定删除这条记录吗？',
      onOk: () => {
        UserApi.delete([row.userId]).then(() => {
          message.success('操作成功');
          getList();
        });
      },
      onCancel: () => {},
    });
  }

  function handleResetPwd(row) {
    Modal.confirm({
      title: '提示',
      content: '此操作将重置该账号密码, 是否继续?',
      onOk: () => {
        UserApi.resetPwd(row).then(() => {
          message.success('操作成功！密码已重置为123456');
          getList();
        });
      },
      onCancel: () => {},
    });
  }

  const checkedRowKeysRef = ref([]);

  function handleCheck(rowKeys: string[]) {
    checkedRowKeysRef.value = rowKeys;
  }

  function handleBatchDelete() {
    Modal.confirm({
      title: '提示',
      content: `确定删除所选的${checkedRowKeysRef.value.length}条数据吗?`,
      onOk: () => {
        UserApi.delete(checkedRowKeysRef.value).then(() => {
          message.success('操作成功！');
          checkedRowKeysRef.value = [];
          handleFilter();
        });
      },
      onCancel: () => {},
    });
  }

  function handleExport() {
    UserApi.export().then((res) => {
      download(res.data, '人员数据.xlsx');
    });
  }
</script>

<style lang="less" scoped>
  .tree-table-wrapper {
    display: flex;
  }

  .tree-wrapper {
    width: 210px;
    margin-right: 20px;
    max-height: calc(100vh - 228px);
    overflow-y: auto;
  }
</style>
